Below is a CNN trained on Alien and Predator images obtained form: https://www.kaggle.com/pmigdal/alien-vs-predator-images
import os
import matplotlib.pyplot as plt
import numpy as np
import cv2
import random
from sklearn.utils import shuffle
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten, Conv2D, Dropout, MaxPooling2D
class_names_label = {'alien':0, 'predator':1}
# Preparing data
def load_data():
datasets = ['alien-vs-predator-images/data/train', 'alien-vs-predator-images/data/test']
size = (150,150)
output = []
for dataset in datasets:
images = []
labels = []
for class_name in os.listdir(dataset):
curr_label = class_names_label[class_name]
for img in os.listdir(dataset + '/' + '/' + class_name):
img_path = dataset + '/' + '/' + class_name + '/' + img
curr_img = cv2.imread(img_path)
curr_img = cv2.resize(curr_img, size)
images.append(curr_img)
labels.append(curr_label)
images = np.asarray(images, dtype='float32')
labels = np.asarray(labels, dtype='float32')
images, labels = shuffle(images, labels)
output.append((images, labels))
return output
(x_train, y_train), (x_test, y_test) = load_data()
x_train /= 255
x_test /= 255
# Exploring Data
sample = [0, 10, 40, 193, 333, 412, 252, 14, 600]
fig = plt.figure()
plt.subplots(3,3, figsize=(16,8))
for i in range(9):
plt.subplot(3,3,i+1)
if y_train[sample[i]] == 0:
title = 'Alien'
else:
title = 'Predator'
plt.title(title)
plt.tight_layout()
plt.imshow(x_train[sample[i]])
# Building Model
model = Sequential()
model.add(Conv2D(32,(3,3), activation='relu', input_shape = (150, 150, 3)))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(32,(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Conv2D(32,(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(128,activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1,activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.summary()
history = model.fit(x_train, y_train, epochs=20)
model.evaluate(x_test, y_test)
model.save('AVPmodel_1.h5')
#Looking at misclassified images
predicted = np.round(model.predict(x_test),0).reshape(200,)
misclassified = predicted != y_test
plt.figure()
plt.subplots(1,4, figsize=(16,8))
misclassified_samples = np.arange(1,5,1)
for i in misclassified_samples:
if y_test[i] == 0:
title = 'Alien'
else:
title = 'Predator'
plt.subplot(1,4,i)
plt.imshow(x_test[misclassified][i])
plt.tight_layout()
plt.title(title)
RESULTS
DISCUSSION
The model overfit on training data and is not able to generalize as well to the test set. The model architecture chosen has 3 convolutional layers making it deep with a total of 1.2M trainable parameters. Such a deep CNN is susceptible to overfitting with only 694 samples.
However, a dropout layer was introduced to reduce overfitting. Also, images were downscaled to 150 x 150 to help combat overfitting.
Improvements